import configUrl from '@/util/url.js';


let rad = (d) => {
	return d * Math.PI / 180.0;
}

let getDistance = (lat1, lng1, lat2, lng2) => {
	let radLat1 = rad(lat1);
	let radLat2 = rad(lat2);
	let a = radLat1 - radLat2;
	let b = rad(lng1) - rad(lng2);
	let s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2) + Math.cos(radLat1) * Math.cos(radLat2) * Math.pow(Math.sin(b / 2), 2)));

	s = s * 6378.137; // EARTH_RADIUS;
	s = Math.round(s * 10000) / 10000; //输出为公里

	let distance = s;
	let distance_str = "";

	if (parseInt(distance) >= 1) {
		distance_str = distance.toFixed(1) + "km";
	} else {
		distance_str = distance * 1000 + "m";
	}

	return s;
}

let deepClone = (target) => {
    // 定义一个变量
    let result;
    // 如果当前需要深拷贝的是一个对象的话
    if (typeof target === 'object') {
    // 如果是一个数组的话
        if (Array.isArray(target)) {
            result = []; // 将result赋值为一个数组，并且执行遍历
            for (let i in target) {
                // 递归克隆数组中的每一项
                result.push(deepClone(target[i]))
            }
         // 判断如果当前的值是null的话；直接赋值为null
        } else if(target===null) {
            result = null;
         // 判断如果当前的值是一个RegExp对象的话，直接赋值
        } else if(target.constructor===RegExp){
            result = target;
        }else {
         // 否则是普通对象，直接for in循环，递归赋值对象的所有值
            result = {};
            for (let i in target) {
                result[i] = deepClone(target[i]);
            }
        }
     // 如果不是对象的话，就是基本数据类型，那么直接赋值
    } else {
        result = target;
    }
     // 返回最终结果
    return result;
}

let cleanData = (target) => {
	let ret = {};
	
	Object.keys(target).forEach((key) => {
		if(target[key] !== '' && target[key] !== null) {
			ret[key] = target[key];
		}
	})
	
	return ret;
}

let formatDateStr = (str, format = 'yyyy年MM月dd日') => {
	let ret = '';

	let date = {
		'y+': str.split(' ')[0].split('-')[0],
		'M+': (str.split(' ')[0].split('-')[1]),
		'd+': str.split(' ')[0].split('-')[2],
		'h+': str.split(' ')[1].split(':')[0],
		'm+': str.split(' ')[1].split(':')[1],
		's+': str.split(' ')[1].split(':')[2]
	}
	
	date['M+'] = (date['M+']).indexOf('0') == 0 ? parseInt(date['M+'].substring(1)) : parseInt(date['M+']);
	date['d+'] = (date['d+']).indexOf('0') == 0 ? parseInt(date['d+'].substring(1)) : parseInt(date['d+']);
	
	for (let i in date) {
		if(new RegExp('('+ i +')').test(format)) {
			format = format.replace(RegExp.$1, date[i])
		}
	}

	return format;
}

let isPtInPoly = (ALon, ALat, APoints) => {
	var iSum = 0,
		iCount;
	var dLon1, dLon2, dLat1, dLat2, dLon;
	if (APoints.length < 3) return false;
	iCount = APoints.length;
	
	for (var i = 0; i < iCount; i++) {
		if (i == iCount - 1) {
			dLon1 = APoints[i][0];
			dLat1 = APoints[i][1];
			dLon2 = APoints[0][0];
			dLat2 = APoints[0][1];
		} else {
			dLon1 = APoints[i][0];
			dLat1 = APoints[i][1];
			dLon2 = APoints[i + 1][0];
			dLat2 = APoints[i + 1][1];
		}
		//以下语句判断A点是否在边的两端点的水平平行线之间，在则可能有交点，开始判断交点是否在左射线上
		if (((ALat >= dLat1) && (ALat < dLat2)) || ((ALat >= dLat2) && (ALat < dLat1))) {
			if (Math.abs(dLat1 - dLat2) > 0) {
				//得到 A点向左射线与边的交点的x坐标：
				dLon = dLon1 - ((dLon1 - dLon2) * (dLat1 - ALat)) / (dLat1 - dLat2);
				if (dLon < ALon)
					iSum++;
			}
		}
	}
	
	if (iSum % 2 != 0)
		return true;
	return false;
}

let getToken = () => {
	let token = uni.getStorageSync('token');
	let ret = ''
	
	if(token){
		ret = token;
	}
	
	return ret;
}

let mergeUrls = (url, obj) => {
	let ret = '';
	let arr = [];
	
	Object.keys(obj).forEach( item => {
		let str = `${item}=${obj[item]}`;
		
		arr.push(str);
	});
	
	let params = arr.join('&');
	
	ret = `${url}?${params}`;
	
	return ret;
}



let compressImage = (patch) => {
	return new Promise((resolve, reject) => {
		plus.zip.compressImage({
			src: patch,
			quality: 62,
			width: '50%',
			height: '50%',
			success: res => {
				resolve(res);
			},
			fail: res => {
				reject(res);
			}
		})
	})
}

let toLogin = () => {
	uni.reLaunch({
	    url: '/pages/login/login'
	});
}

let getRoutes = () => {
	let pages = getCurrentPages();
	let routes = pages.map((page) => page.route);
	
	return routes;
}

let getLocation = async () => {
	return await new Promise((resolve, reject) => {
		let obj = {
			type: 'gcj02',
			success: (res)=> {
				resolve(res);
			},
			fail: (error) => {
				reject();
			}
		};
				
		uni.getLocation(obj);
	})
}

let moveToLocation = async (longitude, latitude, map) => {
	return await new Promise((resolve, reject) => {
		let obj = {
			longitude: longitude,
			latitude: latitude,
			success: () => {
				resolve();
			},
			fail: () => {
				reject();
			}
		}
		
		map.moveToLocation(obj);
	})
}


let chooseLocation = async (data) => {
	return await new Promise((resolve, reject) => {
		let obj = {
			success: () => {
				resolve();
			},
			fail: () => {
				reject();
			}
		}
		
		Object.assign(obj, data);
		
		uni.chooseLocation(obj);
	})
}

let getSystemInfo = async() => {
	return await new Promise((resolve, reject) => {
		uni.getSystemInfo({
			success: (res) => {
				resolve(res);
			}
		});
	});
}

let reverseGeocode= async (longitude, latitude) => {
	return await new Promise((resolve, reject) => {
		let pt = new plus.maps.Point( longitude, latitude );
							
		plus.maps.Map.reverseGeocode(
		pt,
		{},
		(event) => {
			let address = event.address; // 转换后的地理位置
						
			resolve({address: address});
		},
		(e) => {
			reject(e);
		});
	})
};

let chooseImage = async(data) => {
	return await new Promise((resolve, reject) => {
		let obj = {
			count: 1, //默认9
			sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图，默认二者都有
			sourceType: ['album', 'camera'], //从相册选择
			success: (res) => {
			    resolve(res);
			},
			fail: () => {
				reject();
			}
		}
		
		Object.assign(obj, data);
		
		uni.chooseImage(obj);
	})
}

let previewImage = async(data) => {
	return await new Promise((resolve, reject) => {
		let obj = {}
		
		Object.assign(obj, data);
		
		uni.previewImage(obj);
	})
}


let getDictLabel = (value, arr, key, key2 = 'dict_label') => {
	let ret = '';
	let item = {};

	if (value !== undefined) {
		item = arr.find(item => item[key] == value);
		ret = item ? item[key2] : ''
	}
	
	
	return ret;
}


/**
 * Created by Wandergis on 2015/7/8.
 * 提供了百度坐标（BD09）、国测局坐标（火星坐标，GCJ02）、和WGS84坐标系之间的转换
 */
 
//定义一些常量
const x_PI = 3.14159265358979324 * 3000.0 / 180.0;
const PI = 3.1415926535897932384626;
const a = 6378245.0;
const ee = 0.00669342162296594323;

/**
 * GCJ02 转换为 WGS84
 * @param lng
 * @param lat
 * @returns {*[]}
 */

const transformlat = (lng, lat) => {
    var ret = -100.0 + 2.0 * lng + 3.0 * lat + 0.2 * lat * lat + 0.1 * lng * lat + 0.2 * Math.sqrt(Math.abs(lng));
    ret += (20.0 * Math.sin(6.0 * lng * PI) + 20.0 * Math.sin(2.0 * lng * PI)) * 2.0 / 3.0;
    ret += (20.0 * Math.sin(lat * PI) + 40.0 * Math.sin(lat / 3.0 * PI)) * 2.0 / 3.0;
    ret += (160.0 * Math.sin(lat / 12.0 * PI) + 320 * Math.sin(lat * PI / 30.0)) * 2.0 / 3.0;
    return ret
}
 
const transformlng = (lng, lat) => {
    let ret = 300.0 + lng + 2.0 * lat + 0.1 * lng * lng + 0.1 * lng * lat + 0.1 * Math.sqrt(Math.abs(lng));
    ret += (20.0 * Math.sin(6.0 * lng * PI) + 20.0 * Math.sin(2.0 * lng * PI)) * 2.0 / 3.0;
    ret += (20.0 * Math.sin(lng * PI) + 40.0 * Math.sin(lng / 3.0 * PI)) * 2.0 / 3.0;
    ret += (150.0 * Math.sin(lng / 12.0 * PI) + 300.0 * Math.sin(lng / 30.0 * PI)) * 2.0 / 3.0;
    return ret
}
 
/**
 * 判断是否在国内，不在国内则不做偏移
 * @param lng
 * @param lat
 * @returns {boolean}
 */
const out_of_china = (lng, lat) => {
    return (lng < 72.004 || lng > 137.8347) || ((lat < 0.8293 || lat > 55.8271) || false);
}


const gcj02towgs84 = (lng, lat) => {
    if (out_of_china(lng, lat)) {
        return [lng, lat]
    }
    else {
        let dlat = transformlat(lng - 105.0, lat - 35.0);
        let dlng = transformlng(lng - 105.0, lat - 35.0);
        let radlat = lat / 180.0 * PI;
        let magic = Math.sin(radlat);
        magic = 1 - ee * magic * magic;
        let sqrtmagic = Math.sqrt(magic);
        dlat = (dlat * 180.0) / ((a * (1 - ee)) / (magic * sqrtmagic) * PI);
        dlng = (dlng * 180.0) / (a / sqrtmagic * Math.cos(radlat) * PI);
        let mglat = lat + dlat;
        let mglng = lng + dlng;
        return [lng * 2 - mglng, lat * 2 - mglat]
    }
}

const wgs84togcj02 = (lng, lat) => {
    if (out_of_china(lng, lat)) {
        return [lng, lat]
    }
    else {
        let dlat = transformlat(lng - 105.0, lat - 35.0);
        let dlng = transformlng(lng - 105.0, lat - 35.0);
        let radlat = lat / 180.0 * PI;
        let magic = Math.sin(radlat);
        magic = 1 - ee * magic * magic;
        let sqrtmagic = Math.sqrt(magic);
        dlat = (dlat * 180.0) / ((a * (1 - ee)) / (magic * sqrtmagic) * PI);
        dlng = (dlng * 180.0) / (a / sqrtmagic * Math.cos(radlat) * PI);
        let mglat = lat + dlat;
        let mglng = lng + dlng;
        return [mglng, mglat]
    }
}

const uploadFile = (config) => {
	return new Promise((resolve, reject) => {
		let defaultConfig = {
			needAuth: 1
		}
		
		config = Object.assign({}, defaultConfig, config);
		
		uni.uploadFile({
			url: config.url, //仅为示例，非真实的接口地址
		    filePath: config.tempFilePath,
		    name: config.name,
		    formData: config.data,
			header: (() => {
				let base_config = {};
				
			    return base_config;
			})(),
		    complete: (uploadFileRes) => {
				let {data} = uploadFileRes;
				
				if(	data ) {
					data = JSON.parse(data);
					
					if (data.code === 200){
						resolve(data);
					}else{
						uni.showToast({
							title: data.msg,
							duration: 2000,
							icon: 'none'
						});
						
						setTimeout(() => {
							reject();
						} ,2000);
					}
				} else {
					reject();
				}
		    }
		});
	})
}

const formatDate = (cellValue) => {
  if (cellValue == null || cellValue == "") return "";
  var date = new Date(cellValue) 
  var year = date.getFullYear()
  var month = date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1
  var day = date.getDate() < 10 ? '0' + date.getDate() : date.getDate() 
  var hours = date.getHours() < 10 ? '0' + date.getHours() : date.getHours() 
  var minutes = date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes() 
  var seconds = date.getSeconds() < 10 ? '0' + date.getSeconds() : date.getSeconds()
  return year + '-' + month + '-' + day + ' ' + hours + ':' + minutes + ':' + seconds
}

module.exports = {
	rad,
	getDistance,
	deepClone,
	cleanData,
	formatDateStr,
	isPtInPoly,
	mergeUrls,
	toLogin,
	getRoutes,
	compressImage,
	getToken,
	getLocation,
	moveToLocation,
	getSystemInfo,
	chooseLocation,
	reverseGeocode,
	chooseImage,
	previewImage,
	getDictLabel,
	gcj02towgs84,
	wgs84togcj02,
	uploadFile,
	formatDate
}
